package cn.coldleaf.wiki.configure;

import cn.coldleaf.wiki.annotations.IgnoreAop;
import cn.coldleaf.wiki.errors.UserCreateException;
import cn.coldleaf.wiki.errors.UserExistsException;
import cn.coldleaf.wiki.errors.UserNotExistsException;
import cn.coldleaf.wiki.errors.UserUpdateException;
import cn.coldleaf.wiki.pojo.dto.BaseDto;
import cn.coldleaf.wiki.pojo.vo.ResponseVo;
import cn.coldleaf.wiki.utils.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import java.lang.reflect.Method;
import java.util.UUID;

/**
 * @datetime 2023/10/15 下午2:41
 * @user cold
 **/
@Slf4j
@Aspect
@Configuration
@EnableAspectJAutoProxy
public class ControllerAop {

    @Around("execution(* cn.coldleaf.wiki.controllers.*.*(..))")
    public ResponseVo<?> around(ProceedingJoinPoint joinPoint){
        Signature signature = joinPoint.getSignature();
        if (signature instanceof MethodSignature){
            Method method = ((MethodSignature) signature).getMethod();
            if (method.isAnnotationPresent(IgnoreAop.class)){
                try {
                    return (ResponseVo<?>) joinPoint.proceed(joinPoint.getArgs());
                } catch (Throwable e) {
                    log.error("接口执行失败", e);
                }
            }
        }
        Object[] args = joinPoint.getArgs();
        long requestTime = System.currentTimeMillis();
        String requestId = UUID.randomUUID().toString();
        for (Object arg : args) {
            if (arg instanceof BaseDto) {
                ((BaseDto) arg).setTimestamp(requestTime);
                ((BaseDto) arg).setRequestId(requestId);
            }
        }
        ResponseVo<?> ret = null;
        try {
            ret = (ResponseVo<?>) joinPoint.proceed(args);
        }catch (UserNotExistsException e){
            log.error("用户不存在", e);
            ret = ResponseVo.error(ErrorCode.USER_NOT_EXISTS_ERROR);
        }catch (UserExistsException e){
            log.error("用户已存在", e);
            ret = ResponseVo.error(ErrorCode.USER_EXISTS_ERROR);
        }catch (UserCreateException e){
            log.error("用户创建失败", e);
            ret = ResponseVo.error(ErrorCode.USER_CREATE_ERROR);
        } catch (UserUpdateException e){
            log.error("用户修改失败", e);
            ret = ResponseVo.error(ErrorCode.USER_UPDATE_ERROR);
        } catch (Throwable e) {
            log.error("接口执行失败", e);
            ret = ResponseVo.error(ErrorCode.EXCEPTION);
        }
        ret.setRequestId(requestId);
        ret.setRequestTime(requestTime);
        ret.setTimestamp(System.currentTimeMillis());
        return ret;
    }
}
